package com.touchy.touchpad;

import java.awt.Dimension;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;




public class MainServer {
	
	//Server variables
	//private static int InputEvent.
	static Socket clientSocket = null;
	static ServerSocket serverSocket = null;
	static GraphicsDevice device;
	
	public static void main(String[] args) {
		
//		System.out.println(InputEvent.BUTTON1_MASK);
//		System.out.println(InputEvent.BUTTON2_MASK);
//		System.out.println(InputEvent.BUTTON3_MASK);
		//InputEvent.
		//System.exit(0);
		int port_number = 2323;
		System.out.println("New client socket");
		try {
			serverSocket = new ServerSocket(port_number);
			//new clientThread(clientSocket, t, e)).start();
			
		} catch (IOException e) {
			System.out.println(e);
		}
		
		try {
			clientSocket = serverSocket.accept();
			System.out.println("Accepted new connection");
			new ConnectionHandler(clientSocket).run();
		}
		catch(Exception ex) {
			
		}
		
	
	}
	

}

class ConnectionHandler implements Runnable {
    private Socket socket;
    static GraphicsDevice device;
    private static float oldx;
    private static float oldy;
    private static float x;
	private static float y;
	private static int movex;
	private static int movey;
	private static long time;
	private static long oldtime;
	private static long nettime;
	private static float dx;
	private static float dy;
	
	private static int scale = 100;
	
    public ConnectionHandler(Socket socket) {
        this.socket = socket;

        Thread t = new Thread(this);
        t.start();
    }
    
	/**
	 * Move Mouse Method
	 * @param x
	 * @param y
	 */
	public static void moveMouse(int x, int y) {
		GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
		device = environment.getDefaultScreenDevice();
		try {
			Robot r = new Robot();
			r.mouseMove(x, y);
		}
		catch(Exception ex) {}
	}
	
	/**
	 * Button press method
	 * @param BUTTON
	 */
	public static void mouseClick(int BUTTON) {
		GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
		device = environment.getDefaultScreenDevice();
		try {
			Robot r = new Robot(device);
			r.mousePress(BUTTON);
		}
		catch(Exception ex) {}
	
	}
	
	/**
	 * Mouse release
	 * @param BUTTON
	 */
	public static void mouseRelease(int BUTTON) {
		GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
		device = environment.getDefaultScreenDevice();
		try {
			Robot r = new Robot(device);
			//r.mousePress(BUTTON);
			r.mouseRelease(BUTTON);
		}
		catch(Exception ex) {}
	
	}

    @SuppressWarnings("unused")
	public void run() {
        try
        {
            //
            // Read a message sent by client application
            //
        	synchronized(this) {
        	ObjectInputStream dIS = null;
        	dIS = new ObjectInputStream(socket.getInputStream());
        	 boolean stopSend = false;
        	 oldtime = System.currentTimeMillis();
        	 time = System.currentTimeMillis();
        	//System.out.println("Run run");
	        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
	        x = (float) (dim.getWidth() / 2);
	        y = (float)(dim.getHeight() / 2);
	        while(!stopSend) {

	        	DataPacket d = (DataPacket) dIS.readObject();



	        	if(d != null) {
	        		if(d.getDataHeader().getMode() == 0){
	        			if(d.getCommandType().equalsIgnoreCase("mousemove")) {
	        				time = System.currentTimeMillis();
	        				nettime = time - oldtime;

	        				if(nettime == 0)
	        					continue;

	        				if(nettime > 100){
	        					oldx = 0;
	        					oldy = 0;
	        				}
	        				//System.out.println("Time difference " + (time - oldtime));


	        				//System.out.print("old X " + oldx + " oldy " + oldy + " ");
	        				//System.out.println("X " + x + " y " +  y);

	        				if(x + (d.getX() - oldx)/nettime * scale < dim.width && x + (d.getX() - oldx)/nettime * scale >= 0 ){
	        					x += (d.getX() - oldx)/nettime * scale;
	        					//System.out.println("displacement: " + (d.getX() - oldx));
	        					movex = (int)x;
	        				}

	        				if(y + (d.getY() - oldy)/nettime * scale < dim.height && y + (d.getY() - oldy)/nettime * scale >= 0 ){
	        					y += (d.getY() - oldy)/nettime * scale;
	        					//System.out.println("displacement: " + (d.getY() - oldy));
	        					movey = (int)y;
	        				}

	        				moveMouse(movex, movey);
	        				oldtime = time;

	        				oldx = d.getX();
	        				oldy = d.getY();
	        			}
	        			else if(d.getCommandType().equalsIgnoreCase("mouseclick")) {

	        				//see if it was a click up or down
	        				if(!d.isClick()) {
	        					//mouseClick(InputEvent.BUTTON3_MASK);
	        					int click = d.getClickType();
	        					if(click == 16) {
	        						click = InputEvent.BUTTON1_MASK;
	        					}
	        					else if (click == 8) {
	        						click = InputEvent.BUTTON2_MASK;
	        					}
	        					else {
	        						click = InputEvent.BUTTON3_MASK;
	        					}
	        					mouseClick(click);
	        					mouseRelease(click);
	        					System.out.println(d.getClickType());
	        					//System.out.println("MouseClick");
	        				}
	        				else {
	        					int click = d.getClickType();
	        					//mouseRelease(InputEvent.BUTTON3_MASK);
	        					if(click == 16) {
	        						click = InputEvent.BUTTON1_MASK;
	        					}
	        					else if (click == 8) {
	        						click = InputEvent.BUTTON2_MASK;
	        					}
	        					else {
	        						click = InputEvent.BUTTON3_MASK;
	        					}
	        					mouseRelease(click);
	        					System.out.println("MouseRelease");
	        				}
	        			}
	        		}else if(d.getDataHeader().getMode() == 1)
	        		{
	        			if(d.getCommandType().equalsIgnoreCase("mousemove")) {
		        			dx = d.getX();
		        			dy = d.getY();
		        			
		        			x += dx;
		        			y += dy;
//		        			System.out.print("old X" + oldx + " oldy " + oldy + " ");
		        			System.out.println(" x " + x + " y " +  y);
		        			
		        			moveMouse(Math.round(x), Math.round(y));
//		        			oldtime = time;
		        		}
		        		else if(d.getCommandType().equalsIgnoreCase("mouseClick")) {

	        				//see if it was a click up or down
	        				if(!d.isClick()) {
	        					//mouseClick(InputEvent.BUTTON3_MASK);
	        					int click = d.getClickType();
	        					if(click == 16) {
	        						click = InputEvent.BUTTON1_MASK;
	        					}
	        					else if (click == 8) {
	        						click = InputEvent.BUTTON2_MASK;
	        					}
	        					else {
	        						click = InputEvent.BUTTON3_MASK;
	        					}
	        					mouseClick(click);
	        					System.out.println(d.getClickType());
	        					//System.out.println("MouseClick");
	        				}
	        				else {
	        					int click = d.getClickType();
	        					//mouseRelease(InputEvent.BUTTON3_MASK);
	        					if(click == 16) {
	        						click = InputEvent.BUTTON1_MASK;
	        					}
	        					else if (click == 8) {
	        						click = InputEvent.BUTTON2_MASK;
	        					}
	        					else {
	        						click = InputEvent.BUTTON3_MASK;
	        					}
	        					mouseRelease(click);
	        					System.out.println("MouseRelease");
	        				}
		        		}
	        		}
	        	}
            //System.out.println("Recieved Packet");
        	}
        	}

            

        }catch(Exception ex) {
        ex.printStackTrace();
        }
        finally {
        	try {
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
    }
}

